﻿#ifndef _SEARCHFILE_HPP_
#define _SEARCHFILE_HPP_

#include <string>
#if defined(_WIN32)
#include <Windows.h>
#pragma warning(disable:4996 4800)
#elif defined(__linux__)
#include <fnmatch.h>
#include <dirent.h>
#endif

using namespace std;

typedef bool (*ResultCallBack) (void* pUser, bool isDir, const char* name);

static void SearchFile(const char* searchdir,const char* pattern,ResultCallBack rcb,void* pUser)
{
	if (searchdir == NULL || rcb == NULL)
	{
		return;
	}

#if defined(_WIN32)
	char tmp[270] = {'\0'};
	strncpy(tmp,searchdir,270);

	char* p = tmp;
	while(*p != '\0')
	{
		if(*p == '\\')
		{
			*p = '/';
		}
		p++;
	}

	if (*(p-1) != '/')
	{
		*p = '/';
		*(++p) = '\0';
	}

	string dir(tmp);
	if (pattern == NULL)
	{
		dir.append("*.*");
	}
	else
	{
		dir.append(pattern);
	}

	WIN32_FIND_DATA finddata;

	HANDLE hFile = FindFirstFile(dir.c_str(),&finddata);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		return;
	}

	bool bRet = true;

	do
	{
		bool isDir = (finddata.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)?true:false;
		if(!rcb(pUser,isDir,finddata.cFileName))
		{
			break;
		}

		bRet = FindNextFile(hFile,&finddata);
	}while (bRet);

	FindClose(hFile);

#elif defined(__linux__)
	int r = -1;

	DIR* pDir = opendir(searchdir);
	if(pDir == NULL)
	{
		perror("opendir failed");
		return;
	}

	struct dirent* entry = NULL;
	while((entry = readdir(pDir)) != NULL)
	{
		if (pattern != NULL)
		{
			r = fnmatch(pattern, entry->d_name, FNM_PATHNAME|FNM_PERIOD);
			if (r != 0)
			{
				continue;
			}
		}
		
		bool isDir = (entry->d_type == DT_DIR)?true:false;
		if(!rcb(pUser,isDir,entry->d_name))
		{
			break;
		}
	}
	closedir(pDir);

#endif
}


#endif
